<?php

/**
 * JPGraph v4.0.3
 */

namespace lemon\JpGraph\Graph;

use lemon\JpGraph\Util;

/*
 * File:		JPGRAPH_LOG.PHP
 * // Description: Log scale plot extension for JpGraph
 * // Created:	 2001-01-08
 * // Ver:		 $Id: jpgraph_log.php 1106 2009-02-22 20:16:35Z ljp $
 * //
 * // Copyright (c) Asial Corporation. All rights reserved.
 */
define('LOGLABELS_PLAIN', 0);
define('LOGLABELS_MAGNITUDE', 1);

/**
 * @class LogScale
 * // Description: Logarithmic scale between world and screen
 */
class LogScale extends LinearScale
{
	/**
	 * CONSTRUCTOR.
	 *
	 * @param mixed $min
	 * @param mixed $max
	 * @param mixed $type
	 */
	// Log scale is specified using the log of min and max
	public function __construct($min, $max, $type = 'y'){
		parent::__construct($min, $max, $type);
		$this->ticks = new LogTicks('log');
		$this->name  = 'log';
	}

	/**
	 * PUBLIC METHODS.
	 *
	 * @param mixed $a
	 */
	// Translate between world and screen
	public function Translate($a){
		if (!is_numeric($a)) {
			if ($a != '' && $a != '-' && $a != 'x') {
				Util\JpGraphError::RaiseL(11001);
				// ('Your data contains non-numeric values.');
			}

			return 1;
		}
		if ($a < 0) {
			Util\JpGraphError::RaiseL(11002);
			//("Negative data values can not be used in a log scale.");
			exit(1);
		}
		if ($a == 0) {
			$a = 1;
		}

		$a = log10($a);

		return ceil($this->off + ($a * 1.0 - $this->scale[0]) * $this->scale_factor);
	}

	// Relative translate (don't include offset) usefull when we just want
	// to know the relative position (in pixels) on the axis
	public function RelTranslate($a){
		if (!is_numeric($a)) {
			if ($a != '' && $a != '-' && $a != 'x') {
				Util\JpGraphError::RaiseL(11001);
				//('Your data contains non-numeric values.');
			}

			return 1;
		}
		if ($a == 0) {
			$a = 1;
		}
		$a = log10($a);

		return round(($a * 1.0 - $this->scale[0]) * $this->scale_factor);
	}

	// Use bcpow() for increased precision
	public function GetMinVal(){
		if (function_exists('bcpow')) {
			return round(bcpow(10, $this->scale[0], 15), 14);
		}

		return round(pow(10, $this->scale[0]), 14);
	}

	public function GetMaxVal(){
		if (function_exists('bcpow')) {
			return round(bcpow(10, $this->scale[1], 15), 14);
		}

		return round(pow(10, $this->scale[1]), 14);
	}

	// Logarithmic autoscaling is much simplier since we just
	// set the min and max to logs of the min and max values.
	// Note that for log autoscale the "maxstep" the fourth argument
	// isn't used. This is just included to give the method the same
	// signature as the linear counterpart.
	public function AutoScale($img, $min, $max, $maxsteps, $majend = true){
		if ($min == 0) {
			$min = 1;
		}

		if ($max <= 0) {
			Util\JpGraphError::RaiseL(11004);
			//('Scale error for logarithmic scale. You have a problem with your data values. The max value must be greater than 0. It is mathematically impossible to have 0 in a logarithmic scale.');
		}
		if (is_numeric($this->autoscale_min)) {
			$smin = round($this->autoscale_min);
			$smax = ceil(log10($max));
			if ($min >= $max) {
				Util\JpGraphError::RaiseL(25071); //('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.');
			}
		} else {
			$smin = floor(log10($min));
			if (is_numeric($this->autoscale_max)) {
				$smax = round($this->autoscale_max);
				if ($smin >= $smax) {
					Util\JpGraphError::RaiseL(25072); //('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.');
				}
			} else {
				$smax = ceil(log10($max));
			}
		}

		$this->Update($img, $smin, $smax);
	}

	/*
	 * PRIVATE METHODS
	 */
} // @class
